<?php
/**
 * ===============================================
 * 版权所有 2019-2050 青岛铁锤科技有限公司，并保留所有权利。
 * 网站地址: http://www.huaxianling.com
 * ===============================================
 * Author: Happy dong
 * Created Time: 2019-07-08 18:53
 *
 * Version: 2.0
 */

namespace App\Modules\Employee\Repositories;


use App\Exceptions\NotFoundException;
use App\Lib\Utilities;
use App\Models\Salary;
use App\Modules\Employee\Validators\SalaryValidator;
use App\Modules\Order\Repositories\OrderRepository;
use App\Modules\Order\Repositories\RoyaltyRepository;
use App\Modules\Store\Repositories\StoreRepository;
use Flower\Core\Repository\Eloquent\BaseRepository;
use Flower\Core\Repository\Exceptions\ValidatorException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\MessageBag;

class SalaryRepository extends BaseRepository
{
	public function model()
	{
		return Salary::class;
	}

	public function validator()
	{
		return SalaryValidator::class;
	}

	/**
	 * 工资新增批量新增
	 * @param $requestData
	 * @return mixed
	 */
	public function add($requestData){
		DB::beginTransaction();
		$res = $this->model->insert($requestData);
		$res ? DB::commit() : DB::rollBack();
		return $res;
	}

	/**
	 * 定时任务计算所有店铺的员工工资并存入工资表
	 */
//	public function barberSalaryAdd($date){
//		// 获取所有店铺的id
//		$storeIds = (new StoreRepository())->findWhere(['status'=>config('constant.yes')],['id'])->toArray();
//
//		// 计算前一天的工资
//		$date = empty($date)  ? date('Y-m-d',strtotime('-1 day')) : $date;
//		// 计算某店铺的员工工资列表
//		$peopleSalary = array_map(function($v) use($date){
//			return (new OrderRepository())->storeSalaryList($v['id'], $date);
//		},$storeIds);
//
//		$peopleSalary = array_filter($peopleSalary,function($v){
//			return (!empty($v));
//		});
//
//		if(empty($peopleSalary)){
//			$msg = '理发师工资计算结果信息为空';
//			Log::info( $msg.'时间'.date('Y-m-d H:i:s',time()));
//			throw new NotFoundException(['msg'=>$msg]);
//		}
//		$result =array_map(function($v){
//				// 插入数据操作
//				$res = $this->add($v);
//				$res ? '' : Log::info('理发店铺ID号为'.array_column($v,'store_id').'人员工资插入异常！请手动修复！ 时间：'.date('Y-m-d H:i:s', time()));
//				return $res;
//			},$peopleSalary);
//
//			// 处理返回操作的bool值
//		return  array_reduce($result,function($v,$v2){
//			return  $v = $v&&$v2;
//		},true);
//	}



	/**
	 * 获取时间段内某员工的工资详情列表
	 * @param $storeId
	 * @param $userId
	 * @param $startTime
	 * @param $endTime
	 * @return mixed
	 */
	public function getMonthSalary($storeId, $userId,$startTime,$endTime){
		$map = [
			'store_id' =>$storeId,
			'user_id'  => $userId,
		];
		// 获取时间列表
		$monthDays = $this->getMonthDays($startTime, $endTime);
		// 获取查询结果
		$res = $this->model->where($map)->whereDate("created_at", ">=",$startTime)->whereDate("created_at", "<=", $endTime)->selectRaw('DATE_FORMAT(created_at, "%Y-%m") as month, sum(amount +royalty) as total_salary, count(id) as work_days, sum(order_sum) as order_sum')->groupBy('month')->orderBy('month','desc')->get()->toArray();
        // 组合数据
		$res = empty($res) ? 0 : array_column($res, null, 'month');
		foreach ($monthDays as $v){
			$list[$v['month']] = [
				'month' => $v['month'],
				'total_salary' => 0,
				'work_days' => 0,
				'total_days' => $v['days'],
				'order_sum' => 0
			];
			if(!empty($res)){
				$list[$v['month']] = [
					'month' => $v['month'],
					'total_salary' => isset($res[$v['month']]) ? $res[$v['month']]['total_salary'] : 0,
					'work_days' => isset($res[$v['month']]) ? $res[$v['month']]['work_days'] : 0,
					'total_days' => $v['days'],
					'order_sum' => isset($res[$v['month']]) ? $res[$v['month']]['order_sum'] : 0,
				];
			}
		}

		return $list;
	}

	/**
	 * 查询我的工资明细
	 * @param $requestData
	 * @return mixed
	 */
	public function getMySalaryInfo($requestData, $date=''){
		// 计算工资列表
		$salaryList = $this->getMonthSalary($requestData['store_id'],$requestData['user_id'],$requestData['start_time'],$requestData['end_time']);
		$month = empty($date) ? date('Y-m', time()) : date("Y-m",strtotime($date));
		// 员工的今日工资明细
		$todaySalary = (new OrderRepository())->getSingleSalary($requestData['store_id'], $requestData['user_id'],$date);

		$salaryList[$month] = !empty($todaySalary['amount']) ? [
			'month' => $month,
			'total_salary' => $salaryList[$month]['total_salary'] + $todaySalary['amount'],
			'work_days'  => $salaryList[$month]['work_days'] + 1,
			'total_days' => $salaryList[$month]['total_days'],
			'order_sum'  => isset($todaySalary['royalty_list'][config('constant.royaltyType.service')]['nums']) ? $salaryList[$month]['order_sum'] + $todaySalary['royalty_list'][config('constant.royaltyType.service')]['nums'] : $salaryList[$month]['order_sum'],
		] : $salaryList[$month];

		return $salaryList;
	}


	/**
	 * 获取时间区间的月份和对应月份的天数
	 * @param $startTime
	 * @param $endTime
	 * @return array
	 */
	protected function getMonthDays($startTime, $endTime){
		$startMonth = date('Y-m', strtotime($startTime));
		$endMonth   = date('Y-m', strtotime($endTime));
		while($startMonth < $endMonth){
			// 获取每月的天数
			$list[] =[
				'month' => $startMonth,
				'days'  => date('t', strtotime($startMonth)),
			];
			$startMonth = date('Y-m', strtotime($startMonth."+1 month"));
		}
		return $list;
	}

	/**
	 * 定时任务 查询用户排名并插入排名数据表
	 * @return mixed
	 * @throws ValidatorException
	 * @todo 暂停使用
	 */
	public function userRank(){
		$date = date('Y-m-d',time() -86400);
		$res  = $this->model->selectRaw('sum(amount + royalty) as salary, user_id,store_id,created_at')->whereDate('created_at',$date)->with(['store'=>function($query){
			$query->select(['id','adcode']);
		}])->groupBy('user_id')->get()->toArray();
		// 去掉store为NULL的数据
		$userSalaryList = array_filter($res, function($v){
			return (!empty($v['store']));
		});
		$userSalaryList = array_map(function ($v){
			return [
				'salary' =>$v['salary'],
				'user_id' =>$v['user_id'],
				'adcode' => $v['store']['adcode'],
				'rank_date' => date('Y-m-d',strtotime($v['created_at']))
			];
		},$userSalaryList);

		$userSalaryList = Utilities::arrayColumnGroup($userSalaryList, null,'adcode');
		// 进行地区内排名
		$sortList = array_map(function($v){
			$value = array_column($v,'salary');
			array_multisort($value,SORT_DESC,$v);
			return $v;
		},$userSalaryList);
		if(empty($sortList)){
			$msg = '理发师排名信息为空';
			Log::info( $msg.'时间'.date('Y-m-d H:i:s',time()));
			throw new NotFoundException(["msg"=>"理发师排名为空"]);
		}
		$result =array_map(function($v){
			// 插入数据操作
			return $res = (new UserRankRepository())->add(
			// 格式化插入数据
				array_map(function($v2,$v3){
					return [
						'user_id' => $v2['user_id'],
						'adcode' => $v2['adcode'],
						'value' => $v2['salary'],
						'rank_date' => $v2['rank_date'],
						'level' => $v3+1,
					];
				}, $v,array_keys($v)));
		},$sortList);
		// 处理返回操作的bool值
		return array_reduce($result,function($v,$v2){
			return  $v = $v&&$v2;
		},true);
	}


    /**
     * 店长数据中心工资列表
     * @param $storeId
     * @param $startDate
     * @param $endDate
     * @return mixed
     */
    public function getUserSalaryListByStoreId($storeId,$startDate,$endDate,$userId){
	    return $this->model
            ->selectRaw('amount,royalty,FROM_UNIXTIME(salary_date,\'%Y-%m-%d\') as salary_time')
            ->whereRaw('FROM_UNIXTIME(salary_date,\'%Y-%m-%d\') <= "' .$startDate. '" and FROM_UNIXTIME(salary_date,\'%Y-%m-%d\') >="' . $endDate . '" and store_id="'.$storeId.'" and user_id="'.$userId.'" order by salary_time desc')
            ->get()
            ->toArray();
    }

    /**
     * 获取理发师总工资
     * @param $user_id
     * @param $store_id
     */
    public function getBarberGrossWage($user_id,$store_id)
    {
        return $this->model
            ->selectRaw('IFNULL(sum(amount + royalty),0) as price')
            ->where('user_id',$user_id)
            ->where('store_id',$store_id)
            ->first()
            ->price
            ;
    }

    /**
     * 获取全部工资
     */
    public function getBarberGrossWageList($user_id,$store_id)
    {
        $select = [
            'DATE_FORMAT(created_at,\'%Y-%m\') as time',
            'IFNULL(sum(amount + royalty),0) as price'
        ];
        $select = implode($select,',');
        return $this
            ->model
            ->selectRaw($select)
            ->where('store_id',$store_id)
            ->where('user_id',$user_id)
            ->groupBy('time')
            ->orderBy('time','DESC')
            ->get()->toArray();
    }

    /**
     * 获取某月工资
     * @param $user_id
     * @param $store_id
     * @param $month
     */
    public function getBarberMonthGrossWageList($user_id,$store_id,$month)
    {

        return $this->model
            ->selectRaw('royalty,DATE_FORMAT(DATE_SUB(created_at,INTERVAL 1 DAY),"%m-%d") as date')
            ->whereRaw('DATE_FORMAT(created_at,"%Y-%m") = "'.$month.'"')
            ->where('user_id',$user_id)
            ->where('store_id',$store_id)
            ->get();
    }


	/**
	 * 计算店铺员工的基本工资
	 * @param $dateList
	 * @param $storeId
	 * @return mixed
	 */
    public function getEmployeeCost($dateList,$storeId){
    	return $this->model
		    ->where('store_id','=',$storeId)
		    ->whereDate('created_at','>=',$dateList['end_date'])
		    ->whereDate('created_at','<=',$dateList['start_date'])
		    ->sum('amount');
    }

}
